package com.lz.ub.core

import com.lz.ub.Logger
import com.lz.ub.UBCExecute
import com.lz.ub.UBCReader
import java.util.regex.Pattern

/**
 * @author You
 * UBC蓝牙回调数据解析器实现类, 主机端RF主板
 */
class RFMainReader(override val execute: UBCExecute, override val tag: Any?) : UBCReader {

    companion object {

        const val TAG = "RFMainReader"

        //最小响应长度
        const val MIN_LEN = 2

        //多指令合并时延时回调下一指令
        const val MULTI_DELAYED = 20L

        //通用解析分割符
        const val SPLIT = "\r\n"

        //通用OK
        const val OK = "OK"

        //设备连接成功
        const val SUCCESS = "SUCCESS"

        //设备重启或者启动
        const val DEVICE_START = "DEVICE START"

        //连接上的
        const val CONNECTED = "CONNECTED"

        //断开
        const val DISCONNECTED = "DISCONNECTED"

        //正则匹配连接断开,扫描
        private val PATTERN = Pattern.compile("([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})")

        //要写入 OK\r\nINPUT_BLE_DATA:
        const val INPUT_DATA = "INPUT_BLE_DATA:"

        //要写出
        const val OUTPUT_DATA = "OUTPUT_BLE_DATA"

        //异常
        const val ERROR = "ERROR"

        //错误异常
        const val FAIL = "FAIL"

        const val RECEIVED = "+RECEIVED:"

        //'-'开头的Char无用
        const val CHAR_: Byte = 45

        //从设备头信息
        const val CHAR_HEAD: Byte = 0x5A
    }

    private fun log(log: String) {
        Logger.d(TAG, "------read($tag)------>>$log")
    }

    override fun onReceivedData(bytes: ByteArray) {
        if (bytes.size <= MIN_LEN || bytes[0] == CHAR_) {
//            Logger.d(TAG, "received data but not use ")
            return
        }
        val str = String(bytes)
        Logger.v(TAG, "<<$tag>> -read- <<$str>>")
        val arr = str.split(SPLIT)
        if (arr.size < 2 || arr[arr.size - 1] != "") {
            log("******split but is not end with \\r\\n******")
            return
        }
        when (arr[0]) {
            OK -> {
                if (arr[1].startsWith(INPUT_DATA)) { //下一条指令格式为发送消息响应
                    val size = arr[1].substring(INPUT_DATA.length).toIntOrNull()
                    if (size != null) {
                        execute.sendWrite(size)
                    } else {
                        log("****** write input success(${arr[1]}) but has no size ******")
                    }
                } else {
                    execute.sendOK()
                }
            }
            SUCCESS -> execute.sendSuccess()
            DEVICE_START -> execute.sendRestart()
            FAIL, ERROR -> execute.sendError()
            else -> { //基本是先走此逻辑
                if (arr[0].getOrNull(0) == '+') { //+开头
                    if (arr[0].startsWith(RECEIVED)) {
                        val data = arr.getOrNull(2)
                        if (arr.getOrNull(1) == OUTPUT_DATA && data?.endsWith(OK) == true) {
                            val idAndSize = arr[0].substring(RECEIVED.length).split(',')
                            val id = idAndSize.getOrNull(0)?.toIntOrNull()
                            val size = idAndSize.getOrNull(1)?.toIntOrNull()
                            if (id != null && size != null) {
                                val start = hexBytesStart(arr, 1)
                                if (bytes[start] == CHAR_HEAD) {
                                    execute.sendReceivedHex(id, bytes, start, size)
                                } else {
                                    execute.sendReceived(id, data.substring(0, data.length - OK.length))
                                }
                            }
                        }
                    }
                } else {
                    val matcher = PATTERN.matcher(arr[0])
                    if (matcher.find()) { //匹配到
                        val mac = matcher.group()
                        val start = matcher.start()
                        if (start == 0) {//匹配到连上或者断开
                            val end = matcher.end() + 1
                            if (end < arr[0].length) {
                                val left = arr[0].substring(end)
                                if (left.startsWith(CONNECTED)) {
                                    val id = left.substring(CONNECTED.length).trim().toIntOrNull()
                                    if (id != null) {
                                        execute.sendConnected(mac, id)
                                    } else {
                                        log("******connected success (${arr[0]}) but has no id******")
                                    }
                                } else if (left.startsWith(DISCONNECTED)) {
                                    execute.sendDisconnected(mac)
                                }
                            }
                        } else if (start >= 2) {
                            val num = arr[0].substring(0, start - 1).trim().toIntOrNull()
                            if (num != null) {
                                val scans = arr[0].substring(matcher.end() + 1).split(' ', limit = 2)
                                if (scans.size >= 2) {
                                    execute.sendScan(UBCScanResult(num, mac, scans[0], scans[1]))
                                }
                            }
                        }
                    }
                }
            }
        }
    }


    //根据当前的行找出byte的索引
    private fun hexBytesStart(arr: List<String>, index: Int): Int {
        var sum = 0
        for (i in 0..index) {
            sum += arr[i].length
            sum += 2
        }
        return sum
    }
}